-- Copyright (c) 2024 Huawei Technologies Co., Ltd.
-- openUBMC is licensed under Mulan PSL v2.
-- You can use this software according to the terms and conditions of the Mulan PSL v2.
-- You may obtain a copy of Mulan PSL v2 at:
--         http://license.coscl.org.cn/MulanPSL2
-- THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
-- EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
-- MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
-- See the Mulan PSL v2 for more details.

local class = require 'mc.class'
local spi_flash_channel = require 'domain.bios_firmware.package.channel.spi_flash_channel'
local ipmb_channel = require 'domain.bios_firmware.package.channel.ipmb_channel'
local bios_enum = require 'domain.bios_firmware.defs'
local his_channel = require 'domain.bios_firmware.package.channel.hisport_channel'

local ChannelSelector = class()

local channel_config = {
    [bios_enum.UpgradeMode.Cold] = {
        [bios_enum.PackagePeriod.Period2] = {spi_flash_channel},
        [bios_enum.PackagePeriod.Period3] = {spi_flash_channel}
    },
    [bios_enum.UpgradeMode.Hot] = {
        [bios_enum.PackagePeriod.Period2] = {spi_flash_channel},
        [bios_enum.PackagePeriod.Period3] = {ipmb_channel}
    },
    [bios_enum.UpgradeMode.Force] = {
        [bios_enum.PackagePeriod.Period2] = {spi_flash_channel},
        [bios_enum.PackagePeriod.Period3] = {spi_flash_channel}
    },
    [bios_enum.UpgradeMode.PowerOffEffective] = {
        [bios_enum.PackagePeriod.Period2] = {spi_flash_channel},
        [bios_enum.PackagePeriod.Period3] = {spi_flash_channel}
    },
    [bios_enum.UpgradeMode.OnlineForce] = {
        [bios_enum.PackagePeriod.Period2] = {spi_flash_channel},
        [bios_enum.PackagePeriod.Period3] = {spi_flash_channel}
    }
}

local krun_channel_config = {
    [bios_enum.UpgradeMode.Cold] = {
        [bios_enum.PackagePeriod.Period3] = {his_channel}
    },
    [bios_enum.UpgradeMode.Force] = {
        [bios_enum.PackagePeriod.Period3] = {his_channel}
    }
}

function ChannelSelector:ctor()
    self.channel_config = channel_config
    self.krun_channel_config = krun_channel_config
end

-- 冷升级->spi flash
-- 装备升级->spi flash
-- 热升级->ipmb、pcie、spi
function ChannelSelector:select(ctx)
    if not ctx or not ctx.UpgradeMode or not ctx.Period then
        error('channel selector: invalid param')
    end
    local upgrade_mode = self.channel_config[ctx.UpgradeMode]
    if ctx.PackageType == bios_enum.PackageType.Krun then
        upgrade_mode = self.krun_channel_config[ctx.UpgradeMode]
    end
    if not upgrade_mode then
        error(string.format('[bios]set channel: upgrade mode(%s) invalid', ctx.UpgradeMode))
    end
    local channels = upgrade_mode[ctx.Period]
    if not channels then
        error(string.format('[bios]set channel: period(%s) invalid', ctx.Period))
    end
    local channel_tbl = {}
    for _, channel in pairs(channels) do
        table.insert(channel_tbl, channel.new())
    end
    return channel_tbl
end

return ChannelSelector